package com.iwhalecloud.bss.kite.cucc.service.pos.bcmc.handler.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.SymbolConsts;
import com.iwhalecloud.bss.kite.common.unicode.UnicodeOperTypeKite;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosAttachmentDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosAttrDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosOrderDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KiteUpstreamOrderRelationDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.CuccServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalDcPublicConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalPosConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.ExtOrderInfoCache;
import com.iwhalecloud.bss.kite.cucc.service.pos.bcmc.BcmcPosContext;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.util.ChangeTypeUtils;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.scene.service.QuerySceneInstService;
import com.ztesoft.bss.common.bo.LoginInfo;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.StringUtil;
import com.ztesoft.bss.svcability.util.ListUtil;

/**
 * <Description> <br>
 * 组装报文订单信息节点
 *
 * @author XXZ<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2020年12月15日 <br>
 * @since R9.0<br>
 * @see com.iwhalecloud.bss.kite.cucc.service.pos.bcmc.handler.impl <br>
 */
@Service
public class BcmcPosOrderHandler extends AbstractBcmcPosHandler {

    @Autowired
    private QuerySceneInstService querySceneInstService;

    private static Map<String, String> bizTypeMap = new HashMap<>();

    private static Map<String, String> bizTypeNameMap = new HashMap<>();

    static {
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_BUSINESS_CHANGE, "业务变更");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ACCOUNT_CANCEL, "用户预销户");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_PAYMENT_RELATION_CHANGE, "付费关系变更");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_RETURN, "退货");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_PIN_CARD, "销卡");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ADD_TO, "融合追加");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_REPLACE_CHANGE_CARD, "补换卡");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_SHUTDOWN, "强制停机");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_SIM_CARD_ACCT, "SIM卡账户间转移");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_IMEI_UNTIE, "IMEI解绑");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_STOCK_MIGRA, "存量迁移");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_EARLY_PREPAY, "提前终止预付期限");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_CHANGE_BIND_IP, "变更绑定固定IP");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ACCT_RECOVE, "账户恢复活动");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_PLAN_CHANGE_PRIV, "通信计划切换权限");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_LOCK_ACCT_ADMIN, "锁定账户管理员");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_SMS_APPLY, "申请短信接入号");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_OTHER_CHANGE, "其他变更");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ADD_ORDER, "追加订购");


        bizTypeNameMap.put("1001", "商品订购");
        bizTypeNameMap.put("1002", "商品变更");
        bizTypeNameMap.put("1003", "用户停机");
        bizTypeNameMap.put("1004", "用户复机");
        bizTypeNameMap.put("1010", "移机");
        bizTypeNameMap.put("1011", "升降速");
        bizTypeNameMap.put("1015", "过户");

        bizTypeNameMap.put("1009", "资费变更");
        bizTypeNameMap.put("1008", "业务变更");
        bizTypeNameMap.put("1020", "升速");
        bizTypeNameMap.put("1021", "降速");
        bizTypeNameMap.put("1022", "IP地址变更");
        bizTypeNameMap.put("1025", "其他业务属性变更");
        bizTypeNameMap.put("1026", "接口类型变更");
        bizTypeNameMap.put("1027", "接入电路类型变更");
        bizTypeNameMap.put("1028", "接入协议变更");
    }

    @Override
    public void doHandle(BcmcPosContext context) {
        KiteSceneInst sceneInst = CuccPosServiceUtils.getSceneInst(context);
        KitePosOrderDTO order = context.getPosDto().getOrder();
        if (Objects.isNull(order)) {
            order = new KitePosOrderDTO();
        }

        // 设置订单功能信息
        setCommonInfo(context, sceneInst, order);

        // 原单订单信息处理
        dealOldOrderInfo(context, sceneInst, order);

        List<KitePosAttrDTO> attrs = order.getAttrs();
        if (KiteListUtils.isEmpty(attrs)) {
            attrs = new ArrayList<>();
            order.setAttrs(attrs);
        }
        // 业务属性，如收货信息、集团用户信息
        dealBusiAttrs(context, sceneInst, order);

        String createDateStr = CuccPosServiceUtils.getSceneCreateDate(context);

        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        if (Objects.nonNull(loginInfo)) {
            // 获取当前工号ID
            dealPosAttr(attrs, "ORD10114", KiteStringUtils.valueOf(loginInfo.getStaffId()), "工号ID", createDateStr);
            // 获取当前工号编码
            dealPosAttr(attrs, "ORD10115", KiteStringUtils.valueOf(loginInfo.getStaffInfo().getStaffCode()), "工号编码",
                createDateStr);
            // 获取当前工号姓名
            dealPosAttr(attrs, "ORD10116", KiteStringUtils.valueOf(loginInfo.getStaffInfo().getStaffName()), "工号姓名",
                createDateStr);
        }

        // 离网信息
        dealLeaveNetWorkAttrs(context, sceneInst, order);

        // 停机信息
        dealShutdownReasonAttrs(context, sceneInst, order);

        // 销户信息
        dealRemoveMachineReasonAttrs(context, sceneInst, order);

        // 复机信息
        dealRecoveryReasonAttrs(context, sceneInst, order);

        // 个人客户需要将数据传给后端
        if (KiteStringUtils.equals(context.getCustDto().getCustType(), "0")) {
            KitePosAttrDTO attr = new KitePosAttrDTO();
            attr.setCode("CUST_TYPE");
            attr.setType("STRING");
            attr.setStartDate(createDateStr);
            attr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
            attr.setValue(context.getCustDto().getCustType());
            attr.setChangeType("0");
            attr.setCname("客户分类");
            if (!Objects.isNull(ExtOrderInfoCache.get(context.getSceneInstId()))) {
                // 存在原单，则默认不变
                attr.setChangeType("9");
            }
            attrs.add(attr);
        }

        // attrs.addAll(assemblingOrderInfoAttr(context));

        // 其他公共属性和封装附件
        dealCommAttrsAndAttachements(context, sceneInst, order);

        context.getPosDto().setOrder(order);
    }

    //处理复机信息
    private void dealRecoveryReasonAttrs(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {
        List<KiteAttr> removeMachineReasonAttrs = querySceneInstService.listCommonAttrs(context.getSceneInstId(),
            LocalKeyConsts.RECOVERY_INFO_OBJECT_TYPE);
        List<KitePosAttrDTO> attrs = order.getAttrs();
        if (!ListUtil.isEmpty(removeMachineReasonAttrs)) {
            for (KiteAttr kiteAttr : removeMachineReasonAttrs) {
                dealOrderAttr(context, attrs, kiteAttr);
            }
        }
    }

    // 获取修改标识
    private String getChangeType(BcmcPosContext context) {
        String changeType = ChangeTypeUtils.getChangeType(ActionType.A.name());
        KitePosDTO posDto = ExtOrderInfoCache.get(context.getSceneInstId());
        if (!Objects.isNull(posDto)) {
            changeType = ChangeTypeUtils.getChangeType(ActionType.M.name());
        }

        return changeType;
    }

    /*
     * 设置订单公共信息
     */
    private void setCommonInfo(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {

        // 场景对象操作类型 订购，退单，初审，重提等
        // 业务变更bizType传服务提供ID
        setBizType(context, sceneInst, order);
        order.setChangeFees(UnicodeOperTypeKite.OPERTYPE_1009.equals(order.getBizType()) ? "1" : "0");
        order.setOrderType("0");
        order.setProvinceCode(context.getCustDto().getProvinceCode());
        order.setEparchyCode(context.getCustDto().getEparchyCode());
        if (Objects.isNull(context.getCustDto().getEparchyCode())) {
            order.setEparchyCode(context.getCustDto().getRegionId());
        }
        order.setChangeType(getChangeType(context));
    }

    /**
     * 设置业务操作类型
     */
    private void setBizType(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {
        if (KiteStringUtils.equals("1008", sceneInst.getOperType())) {
            String serviceOfferId = sceneInst.getServiceOfferId();
            if (KiteStringUtils.equals("2826", serviceOfferId)) {
                serviceOfferId = "1008";
            } else if (KiteStringUtils.equals("2549", serviceOfferId)) {
                serviceOfferId = "1015";
            }
            order.setBizType(serviceOfferId);
            order.setBizTypeName(bizTypeMap.get(serviceOfferId));
        }
        else {
            order.setBizType(sceneInst.getOperType());
            order.setBizTypeName(bizTypeNameMap.get(sceneInst.getOperType()));
        }
    }

    /**
     * 存在原单信息处理
     */
    private void dealOldOrderInfo(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {
        // 原单
        String orderId = this.querySceneInstService.getExtParameterValue(sceneInst.getSceneInstId(), "sourceOrderId");
        if (StringUtil.isNotEmpty(orderId)) {
            List<KiteUpstreamOrderRelationDTO> orderRelationDTOList = new ArrayList<>();
            KiteUpstreamOrderRelationDTO orderRelationDTO = new KiteUpstreamOrderRelationDTO();
            orderRelationDTO.setGoodsInstanceId(
                querySceneInstService.getExtParameterValue(context.getSceneInstId(), "mainOfferInstId"));
            orderRelationDTO.setUpstreamOrderId(orderId);
            orderRelationDTOList.add(orderRelationDTO);
            order.setUpstreamOrderRelation(orderRelationDTOList);
        }
        // 原单
        String resourceCheckOrderId = this.querySceneInstService.getExtParameterValue(sceneInst.getSceneInstId(),
            "resourceCheckOrderId");
        if (StringUtil.isNotEmpty(resourceCheckOrderId)) {
            List<KiteUpstreamOrderRelationDTO> orderRelationDTOList = new ArrayList<>();
            KiteUpstreamOrderRelationDTO orderRelationDTO = new KiteUpstreamOrderRelationDTO();
            orderRelationDTO.setGoodsInstanceId(
                querySceneInstService.getExtParameterValue(context.getSceneInstId(), "mainOfferInstId"));
            orderRelationDTO.setUpstreamOrderId(resourceCheckOrderId);
            orderRelationDTOList.add(orderRelationDTO);
            order.setUpstreamOrderRelation(orderRelationDTOList);
        }
    }

    /**
     * 处理业务属性
     */
    private void dealBusiAttrs(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {
        List<KiteAttr> busiAttrs = Lists.newArrayList();
        List<DcPublic> publics = DcPublicCache.get(LocalDcPublicConsts.BUSI_ATTR_MODULE);
        publics.forEach(ppp -> {
            busiAttrs.addAll(querySceneInstService.listCommonAttrsByModuleId(context.getSceneInstId(), ppp.getPcode()));
        });

        List<KitePosAttrDTO> attrs = order.getAttrs();
        for (KiteAttr kiteAttr : busiAttrs) {
            // 属性值为空不传到下游系统
            if (KiteStringUtils.isEmpty(kiteAttr.getValue())) {
                continue;
            }

            // 处理属性
            dealOrderAttr(context, attrs, kiteAttr);

            if (KiteStringUtils.equals(kiteAttr.getFieldName(), "cust_manager_name")) {
                order.setInitCustMgrName(kiteAttr.getValue());
            }
            if (KiteStringUtils.equals(kiteAttr.getFieldName(), "cust_manager_num")) {
                order.setInitCustMgrPhone(kiteAttr.getValue());
            }
        }

        // 售前信息
        List<KiteAttr> preSalesInfoAttrs = busiAttrs.stream()
            .filter((attr) -> LocalKeyConsts.PROD_ATTR_SHOW_TYPE_S.equals(attr.getShowType()))
            .collect(Collectors.toList());
        if (!ListUtil.isEmpty(preSalesInfoAttrs)) {
            for (KiteAttr kiteAttr : preSalesInfoAttrs) {
                dealOrderAttr(context, attrs, kiteAttr);
                if (!attrs.stream().anyMatch((attr) -> attr.getCode().equals(kiteAttr.getFieldName()))) {
                }
            }
        }

    }

    /**
     * 处理离网信息
     */
    private void dealLeaveNetWorkAttrs(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {
        List<KiteAttr> leaveNetWorkAttrs = querySceneInstService.listCommonAttrs(context.getSceneInstId(),
            LocalKeyConsts.LEAVENETWORK_OBJECT_TYPE);
        List<KitePosAttrDTO> attrs = order.getAttrs();
        if (!ListUtil.isEmpty(leaveNetWorkAttrs)) {
            for (KiteAttr kiteAttr : leaveNetWorkAttrs) {
                dealOrderAttr(context, attrs, kiteAttr);
            }
        }
    }

    /**
     * 处理停机信息
     */
    private void dealShutdownReasonAttrs(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {
        List<KiteAttr> shutdownReasonAttrs = querySceneInstService.listCommonAttrs(context.getSceneInstId(),
            LocalKeyConsts.SHUTDOWN_OBJECT_TYPE);
        List<KitePosAttrDTO> attrs = order.getAttrs();
        if (!ListUtil.isEmpty(shutdownReasonAttrs)) {
            for (KiteAttr kiteAttr : shutdownReasonAttrs) {
                dealOrderAttr(context, attrs, kiteAttr);
            }
        }
    }

    /**
     * Description: <br>
     * 处理销户信息
     */
    private void dealRemoveMachineReasonAttrs(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {
        List<KiteAttr> removeMachineReasonAttrs = querySceneInstService.listCommonAttrs(context.getSceneInstId(),
            LocalKeyConsts.REMOVEMACHINE_OBJECT_TYPE);
        List<KitePosAttrDTO> attrs = order.getAttrs();
        if (!ListUtil.isEmpty(removeMachineReasonAttrs)) {
            for (KiteAttr kiteAttr : removeMachineReasonAttrs) {
                dealOrderAttr(context, attrs, kiteAttr);
            }
        }
    }

    /**
     * Description: <br>
     * 封装其他公共信息和附件信息
     */
    private void dealCommAttrsAndAttachements(BcmcPosContext context, KiteSceneInst sceneInst, KitePosOrderDTO order) {
        List<KiteAttr> commAttrs = querySceneInstService.listCommonAttrs(context.getSceneInstId(),
            KeyConsts.COMMON_OBJECT_TYPE);

        List<KitePosAttrDTO> attrs = order.getAttrs();
        String createDateStr = CuccPosServiceUtils.getSceneCreateDate(context);
        List<KiteAttr> commAttr = commAttrs.stream()
            .filter((attr) -> !LocalKeyConsts.COMMON_ATTR_KEY_ATTACHMENT.equals(attr.getFieldName()))
            .collect(Collectors.toList());
        if (!KiteListUtils.isEmpty(commAttr)) {
            for (KiteAttr kiteAttr : commAttr) {
                if ("ORD10022".equals(kiteAttr.getFieldName())) {
                    order.setRemark(kiteAttr.getValue() == null ? "" : kiteAttr.getValue());
                }
                else {
                    dealPosAttr(attrs, kiteAttr.getFieldName(), Optional.ofNullable(kiteAttr.getValue()).orElse(""),
                        kiteAttr.getCname(), createDateStr);
                }
            }
        }

        List<KiteAttr> attachements = commAttrs.stream()
            .filter((attr) -> LocalKeyConsts.COMMON_ATTR_KEY_ATTACHMENT.equals(attr.getFieldName()))
            .collect(Collectors.toList());

        if (!KiteListUtils.isEmpty(attachements)) {
            KiteAttr kiteAttr = attachements.get(0);
            List<KitePosAttachmentDTO> attachments = new ArrayList<>();

            String jsonStr = kiteAttr.getValue();
            if (!KiteStringUtils.isEmpty(jsonStr)) {
                JSONArray arrs = JSONArray.parseArray(jsonStr);
                for (int i = 0; i < arrs.size(); i++) {
                    JSONObject obj = arrs.getJSONObject(i);
                    KitePosAttachmentDTO attaDto = new KitePosAttachmentDTO();
                    attaDto.setUrl(obj.getString("attachmentUrl"));
                    attaDto.setCatagory(obj.getString("fileType").replace("ATTACHMENTS_TYPE_", ""));
                    attaDto.setName(
                        KiteStringUtils.join(obj.getString("fileName"), SymbolConsts.PERIOD, obj.getString("type")));
                    attaDto.setUploadTime(obj.getString("createDate"));
                    String changeType = ChangeTypeUtils.getChangeType(obj.getString("actionType"));
                    if (KiteStringUtils.isEmpty(changeType)) {
                        changeType = ChangeTypeUtils.getChangeType(ActionType.A.name());
                    }
                    else {
                        changeType = ChangeTypeUtils.getChangeType(obj.getString("actionType"));
                    }
                    attaDto.setChangeType(changeType);
                    attachments.add(attaDto);
                }
            }
            order.setAttachments(attachments);
        }
    }

    /**
     * Description: <br>
     * 订单属性公共处理方法
     */
    private void dealOrderAttr(BcmcPosContext context, List<KitePosAttrDTO> attrs, KiteAttr kiteAttr) {
        String startDate = CuccPosServiceUtils.getSceneCreateDate(context);
        String value = kiteAttr.getValue() == null ? "" : kiteAttr.getValue();
        dealPosAttr(attrs, kiteAttr.getFieldName(), value, kiteAttr.getCname(), startDate);
    }

    /**
     * Description: <br>
     * 通用属性封装
     */
    private void dealPosAttr(List<KitePosAttrDTO> attrs, String code, String value, String cname, String startDate) {
        // 根据属性编码获取属性对象
        KitePosAttrDTO posAttr = attrs.stream().filter(attr -> KiteStringUtils.equals(code, attr.getCode())).findFirst()
            .orElse(null);

        if (Objects.isNull(posAttr)) {
            // 新增属性
            KitePosAttrDTO staffIdAttr = new KitePosAttrDTO();
            staffIdAttr.setCode(code);
            staffIdAttr.setType(LocalPosConsts.ATTR_TYPE_STRING);
            staffIdAttr.setStartDate(startDate);
            staffIdAttr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
            staffIdAttr.setValue(value);
            staffIdAttr.setCname(cname);
            staffIdAttr.setChangeType(ChangeTypeUtils.getChangeType(ActionType.A.name()));
            attrs.add(staffIdAttr);
        }
        else {
            // 如果有匹配的属性并且值不相等,那么取场景中的数据更新转单
            posAttr.setChangeType(ChangeTypeUtils.getChangeType(ActionType.K.name()));
            posAttr.setCname(cname);
            if (!KiteStringUtils.isEqual(value, posAttr.getValue())) {
                posAttr.setChangeType(ChangeTypeUtils.getChangeType(ActionType.M.name()));
                posAttr.setOriginValue(posAttr.getValue());
            }
            posAttr.setValue(value);
        }
    }

    /**
     * Description: <br>
     * 组装公共信息模块-订单信息属性(后续补充后待删除)
     *
     * @author XXZ<br>
     * @taskId <br>
     *         <br>
     */
    private List<KitePosAttrDTO> assemblingOrderInfoAttr(BcmcPosContext context) {
        List<KitePosAttrDTO> attrs = Lists.newArrayList();

        attrs.add(genKitePosAttrDTO(context, "ORD10004", "0", "", "资源是否预占", "0"));
        attrs.add(genKitePosAttrDTO(context, "ORD10005", "0", "", "开通方式", "0"));
        attrs.add(genKitePosAttrDTO(context, "ORD10001", "0", "", "订单性质", "0"));
        attrs.add(genKitePosAttrDTO(context, "ORD10002", "1", "", "起租方式", "0"));

        return attrs;
    }

    private KitePosAttrDTO genKitePosAttrDTO(BcmcPosContext context, String fieldName, String value, String oldValue,
        String cname, String changeType) {
        KitePosAttrDTO attr = new KitePosAttrDTO();
        attr.setCode(fieldName);
        attr.setType(LocalPosConsts.ATTR_TYPE_STRING);
        attr.setStartDate(CuccPosServiceUtils.getSceneCreateDate(context));
        attr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
        attr.setValue(value);
        attr.setOriginValue(oldValue);
        attr.setCname(cname);
        attr.setChangeType(changeType);
        return attr;
    }
}
